package oop.ex2.compiler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;

import oop.ex2.enums.CommentEnum;
import oop.ex2.enums.MethodEnum;
import oop.ex2.enums.VariableEnum;
import oop.ex2.objects.Method;
import oop.ex2.objects.Variable;

public class Compiler {
    private boolean isInsideComment = false;
    private ArrayList<String> fileContents;
    private HashMap<String, Method> methodsDeclared;
    private ArrayList<Variable> globalVariables;

    public Compiler(ArrayList<String> fileContents, ArrayList<Variable> globalVariables,
            HashMap<String, Method> methodsDeclared) {
        this.fileContents = fileContents;
        this.globalVariables = globalVariables;
        this.methodsDeclared = methodsDeclared;
    }

    public void checkCode() throws VariablesException {
         addMethodsAndGlobalVariables();
         checkIfWhile();
    }

    private void checkIfWhile() {
        for (int i = 0; i < fileContents.size(); i++) {       
        }
        
    }

    private void addMethodsAndGlobalVariables() throws VariablesException {
        for (int i = 0; i < fileContents.size(); i++) {
            checkComments(fileContents.get(i), i);
            for (MethodEnum methodEnum : MethodEnum.values()) {
                Matcher methodMatcher = methodEnum.getEnumPattern().matcher(fileContents.get(i));
                if (methodMatcher.matches()) { // Find all the methods.
                    String name = methodMatcher.group(2);
                    String returnType = methodMatcher.group(1);
                    String[] fullArguments = methodMatcher.group(3).split(",");
                    HashMap<String, String> arguments = new HashMap<String, String>();
                    if (!fullArguments[0].equals("")) {
                        for (String singleArgument : fullArguments) {
                            String[] oneArgument = singleArgument.split(" ");
                            arguments.put(oneArgument[1], oneArgument[0]);
                        }
                    }
                    methodsDeclared.put(name, new Method(name, returnType, arguments));
                    break;
                }
            }
            for (VariableEnum variableEnum : VariableEnum.values()) { // Find
                                                                      // all
                                                                      // the
                                                                      // fields.
                Matcher variableMatcher = variableEnum.getEnumPattern().matcher(fileContents.get(i));
                if (variableMatcher.matches()) {
                    String type = variableMatcher.group(1);
                    String name = variableMatcher.group(2);
                    String value = variableMatcher.group(3);
                    globalVariables.add(new Variable(name, type, value, methodsDeclared, globalVariables));
                    break;
                }
            }
        }
    }

    private void checkComments(String line, int i) {
        for (CommentEnum comment : CommentEnum.values()) {
            Matcher commentMatcher = comment.getEnumPattern().matcher(line);
            if (isInsideComment) {
                fileContents.set(i, "");
            }
            while (commentMatcher.find()) {
                if (comment.equals(CommentEnum.MULTI_LINE_START)) {
                    isInsideComment = true;
                } else {
                    isInsideComment = false;
                }
                fileContents.set(i, fileContents.get(i).replace(commentMatcher.group(), " "));
            }
        }
    }
}
